package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.dto.admin.SetEnterAgentDto;
import com.frejoys.common.dto.admin.UpdateAgentDto;
import com.frejoys.common.dto.app.AddStoreEnterDto;
import com.frejoys.common.dto.app.UpStoreEnterDto;
import com.frejoys.common.dto.common.PageDto;
import com.frejoys.common.enums.*;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.util.AppConfigUtil;
import com.frejoys.common.util.CommonUtil;
import com.frejoys.common.util.TimeUtil;
import com.frejoys.common.vo.app.StoreEnterListVo;
import com.frejoys.common.vo.app.StoreEnterVo;
import com.frejoys.dao.entity.*;
import com.frejoys.dao.mapper.AdminVerifyMapper;
import com.frejoys.dao.mapper.AgentStoreMapper;
import com.frejoys.dao.mapper.StoreEnterMapper;
import com.frejoys.dao.mapper.UserMapper;
import com.frejoys.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class StoreEnterServiceImpl extends ServiceImpl<StoreEnterMapper, StoreEnter> implements StoreEnterService {


    private final UserMapper userMapper;

    private final UserService userService;

    private final AdminVerifyMapper adminVerifyMapper;

    private final ReasonService reasonService;

    private final StoreEnterMapper storeEnterMapper;

    private final AgentStoreMapper agentStoreMapper;

    private final AgentStoreService agentStoreService;

    @Override
    public Long getAgentUserId(Long userId) {
        LambdaQueryWrapper<StoreEnter> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreEnter::getAgentUserId)
                .eq(StoreEnter::getUserId, userId);
        StoreEnter e = getOnly(wrapper);
        return e != null ? e.getAgentUserId() : null;
    }

    //商家入驻申请
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer insertStoreEnter(Long userId,AddStoreEnterDto dto) {

//        User user = userService.getInfo(userId);
//
//        //商家不能商家入驻
//        if (CommonUtil.bitExistOffset(user.getRole(),EUserRole.store.getValue())){
//            throw new GeneralException(HttpStatus.notNormalUserError);
//        }
        //校验代理人
        if (dto.getAgentUserId() != null){
            userService.verifyAgentUserId(dto.getAgentUserId());
        }
        // 查询是否已提交申请
        if (applyPending(userId)){
            throw new GeneralException(HttpStatus.repetitionError);
        }

        StoreEnter storeEnter = new StoreEnter();

        if (dto.getAgentUserId() != null){
            storeEnter.setAgentUserId(dto.getAgentUserId());
        }

        storeEnter.setUserId(userId);
        storeEnter.setTel(dto.getTel());
        storeEnter.setName(dto.getName());
        storeEnter.setBusinessLicense(dto.getBusinessLicense());
        storeEnter.setIdCardImage(dto.getIdCardImage());
        baseMapper.insert(storeEnter);

        AdminVerify adminVerify = new AdminVerify();
        adminVerify.setCommonId(storeEnter.getId());
        adminVerify.setType(EAdminVerifyType.storeEnter.getValue());
        adminVerify.setCreateTime(TimeUtil.unixTime());
        adminVerify.setUpdateTime(TimeUtil.unixTime());
        adminVerify.setStatus(EAdminVerifyStatus.initial.getValue());

        // 没有代理人时直接交给管理员审核
        if (dto.getAgentUserId() == null){
            adminVerify.setStatus(EAdminVerifyStatus.agentPass.getValue());
        }

        return adminVerifyMapper.insert(adminVerify);
    }



    //代理人查询商家入驻列表
    @Override
    public List<StoreEnterListVo> agentStoreEnterInfo(Long agentUserId, PageDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());
        page.setSearchCount(false);

        List<StoreEnterListVo> list  = new ArrayList<>();

        LambdaQueryWrapper<StoreEnter> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(StoreEnter::getId)
                .eq(StoreEnter::getAgentUserId,agentUserId);
        List<StoreEnter> storeEnters = baseMapper.selectList(wrapper);

        if (!storeEnters.isEmpty()) {

            List<Integer> storeEnterId = storeEnters.stream().map(StoreEnter::getId).toList();
            list = adminVerifyMapper.agentStoreEnterInfo(page, storeEnterId,EAdminVerifyType.storeEnter.getValue());

            if (!list.isEmpty()) {

                //查询用户昵称
                List<Long> userIds = list.stream().map(StoreEnterListVo::getUserId).toList();
                List<User> userList = userMapper.getUserList(userIds, EStatus.on.getValue());
                Map<Long, String> userMap = userList.stream().collect(Collectors.toMap(User::getId, User::getNickname));

                list.forEach(storeEnter -> {

                    if (userMap.containsKey(storeEnter.getUserId())) {
                        storeEnter.setNickname(userMap.get(storeEnter.getUserId()));
                    }
                    storeEnter.setBusinessLicense(AppConfigUtil.getUrlPrefix(storeEnter.getBusinessLicense()));
                    storeEnter.setIdCardImage(AppConfigUtil.getUrlPrefix(storeEnter.getIdCardImage()));

                });
            }
        }
        return list;
    }


    //添加代理人
    @Override
    public Integer updateAgent(UpdateAgentDto dto) {

        LambdaUpdateWrapper<StoreEnter> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StoreEnter::getId,dto.getId());
        updateWrapper.set(StoreEnter::getAgentUserId, dto.getAgentUserId());

        return baseMapper.update(updateWrapper);
    }



    //修改代理人
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer setEnterAgent(SetEnterAgentDto dto) {

        LambdaUpdateWrapper<StoreEnter> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StoreEnter::getId,dto.getId())
                    .set(StoreEnter::getAgentUserId,dto.getAgentUserId());
        int i = baseMapper.update(updateWrapper);

        //修改 代理服务商家表代理人
        if (dto.getType() == ESetEnterAgentType.all.getValue()){

            LambdaQueryWrapper<StoreEnter> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(StoreEnter::getUserId)
                    .eq(StoreEnter::getId,dto.getId());

            StoreEnter storeEnter = getOnly(queryWrapper);

            //查询代理服务商家表是否存在这个用户信息
            LambdaQueryWrapper<AgentStore> qWrapper = new LambdaQueryWrapper<>();
            qWrapper.select(AgentStore::getId)
                    .eq(AgentStore::getUserId,storeEnter.getUserId());
            List<AgentStore> agentStores = agentStoreMapper.selectList(qWrapper);

            if (!agentStores.isEmpty()){
                LambdaUpdateWrapper<AgentStore> wrapper = new LambdaUpdateWrapper<>();
                wrapper.in(AgentStore::getUserId,storeEnter.getUserId())
                        .set(AgentStore::getAgentUserId,dto.getAgentUserId());

                agentStoreMapper.update(wrapper);
            }
        }
        return i;
    }


    @Override
    public boolean applyPending(Long userId) {
        LambdaQueryWrapper<StoreEnter> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreEnter::getUserId,userId);
        return baseMapper.exists(wrapper);
    }

    @Override
    public StoreEnterVo queryStoreEnter(Long userId) {
        LambdaQueryWrapper<StoreEnter> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreEnter::getUserId,userId);
        StoreEnter storeEnter = getOnly(wrapper);
        StoreEnterVo storeEnterVo = BeanUtil.copyProperties(storeEnter, StoreEnterVo.class);
        if (storeEnterVo == null) {
            return null;
        }
        if (StrUtil.isNotEmpty(storeEnterVo.getIdCardImage())) {
            storeEnterVo.setIdCardImageUrl(AppConfigUtil.getUrlPrefix(storeEnterVo.getIdCardImage()));
        }
        if (StrUtil.isNotEmpty(storeEnterVo.getBusinessLicense())) {
            storeEnterVo.setBusinessLicenseUrl(AppConfigUtil.getUrlPrefix(storeEnterVo.getBusinessLicense()));
        }
        if (storeEnterVo.getAgentUserId() != null){
            // 查询代理人信息
            User agentUser = userService.getInfo(storeEnterVo.getAgentUserId());
            if (agentUser != null) {
                storeEnterVo.setAgentUserNickName(agentUser.getNickname());
                storeEnterVo.setAgentUserPhone(agentUser.getPhone());
            }
        }
        LambdaQueryWrapper<AdminVerify> adminVerifyQueryWrapper = new LambdaQueryWrapper<>();
        adminVerifyQueryWrapper.select(AdminVerify::getId,AdminVerify::getReasonId,AdminVerify::getRemark,AdminVerify::getStatus);
        adminVerifyQueryWrapper.eq(AdminVerify::getType,EAdminVerifyType.storeEnter.getValue());
        adminVerifyQueryWrapper.eq(AdminVerify::getCommonId,storeEnter.getId());
        AdminVerify adminVerify = adminVerifyMapper.selectOne(adminVerifyQueryWrapper,false);
        // 如果被驳回  查询审核失败原因
        if (adminVerify != null) {
            storeEnterVo.setStatus(adminVerify.getStatus());
            if (EVerifyStatus.reject.getValue().equals(adminVerify.getStatus())) {
                LambdaQueryWrapper<Reason> reasonQueryWrapper = new LambdaQueryWrapper<>();
                reasonQueryWrapper.select(Reason::getId,Reason::getContent);
                reasonQueryWrapper.eq(Reason::getId,adminVerify.getReasonId());
                Reason reason = reasonService.getOnly(reasonQueryWrapper);
                if (reason != null) {
                    storeEnterVo.setReason(reason.getContent());
                }
                storeEnterVo.setRemark(adminVerify.getRemark());
            }
        }
        return storeEnterVo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer upStoreEnter(UpStoreEnterDto dto) {

        LambdaQueryWrapper<AdminVerify> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AdminVerify::getStatus)
                .eq(AdminVerify::getCommonId,dto.getId())
                .eq(AdminVerify::getType,EAdminVerifyType.storeEnter.getValue());
        AdminVerify adminVerify = adminVerifyMapper.selectOne(wrapper);

        if (adminVerify == null){
            throw new GeneralException(HttpStatus.storeEnterError);
        }
        //审核未通过才可以修改
        if (adminVerify.getStatus() != EAdminVerifyStatus.notPass.getValue()){
            throw new GeneralException(HttpStatus.onSaleEditError);
        }

        LambdaUpdateWrapper<StoreEnter> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(StoreEnter::getId,dto.getId());

        if (dto.getAgentUserId() != null){
            updateWrapper.set(StoreEnter::getAgentUserId,dto.getAgentUserId());
        }
        if (StrUtil.isNotEmpty(dto.getTel())){
            updateWrapper.set(StoreEnter::getTel,dto.getTel());
        }
        if (StrUtil.isNotEmpty(dto.getBusinessLicense())){
            updateWrapper.set(StoreEnter::getBusinessLicense,dto.getBusinessLicense());
        }
        if (StrUtil.isNotEmpty(dto.getIdCardImage())){
            updateWrapper.set(StoreEnter::getIdCardImage,dto.getIdCardImage());
        }
        if (StrUtil.isNotEmpty(dto.getName())){
            updateWrapper.set(StoreEnter::getName,dto.getName());
        }

        //修改商家入驻申请表
        baseMapper.update(updateWrapper);

        //修改管理员审核表状态
        LambdaUpdateWrapper<AdminVerify> aUpdateWrapper = new LambdaUpdateWrapper<>();
        aUpdateWrapper.eq(AdminVerify::getCommonId,dto.getId())
                .eq(AdminVerify::getType,EAdminVerifyType.storeEnter.getValue())
                .set(AdminVerify::getStatus,EAdminVerifyStatus.initial.getValue());

        return adminVerifyMapper.update(aUpdateWrapper);
    }

}
